package com.hxtec.polaris.service.impl;

import com.hxtec.polaris.commons.MapperUtils;
import com.hxtec.polaris.commons.api.vo.Result;
import com.hxtec.polaris.commons.thread.UpdateHotScoreRunable;
import com.hxtec.polaris.entity.*;
import com.hxtec.polaris.mapper.ShopProductBaseMapper;
import com.hxtec.polaris.mapper.ShopProductSaleAttrMapper;
import com.hxtec.polaris.mapper.ShopProductSaleAttrValueMapper;
import com.hxtec.polaris.mapper.ShopProductVariantAttrValueMapper;
import com.hxtec.polaris.mapper.ShopProductVariantImageMapper;
import com.hxtec.polaris.mapper.ShopProductVariantMapper;
import com.hxtec.polaris.service.ProductService;
import com.hxtec.polaris.service.StockService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * @author Caps
 * @date 2019/11/16
 */
@Service
public class ProductServiceImpl implements ProductService {

    private final ShopProductVariantMapper skuMapper;

    private final ShopProductBaseMapper spumapper;

    private final ShopProductSaleAttrMapper productSaleAttrMapper;

    private final ShopProductVariantImageMapper imageMapper;

    private final ShopProductVariantAttrValueMapper variantAttrValueMapper;

    private final StockService shopStockService;

    public ProductServiceImpl(ShopProductVariantMapper skuMapper, ShopProductBaseMapper spumapper, ShopProductSaleAttrMapper productSaleAttrMapper, ShopProductVariantImageMapper imageMapper, ShopProductVariantAttrValueMapper variantAttrValueMapper, RedisTemplate redisTemplate, StockService shopStockService) {
        this.skuMapper = skuMapper;
        this.spumapper = spumapper;
        this.productSaleAttrMapper = productSaleAttrMapper;
        this.imageMapper = imageMapper;
        this.variantAttrValueMapper = variantAttrValueMapper;
        this.shopStockService = shopStockService;
    }

    /**
     * 根据sku从数据库获取带图片信息的商品信息
     * @param sku
     * @return
     */
    @Override
    public ShopProductVariant getSkuProductBySku(Integer sku) {
        //商品
        ShopProductVariant shopProductVariant = skuMapper.selectByPrimaryKey(sku);
        Example example=new Example(ShopProductVariantImage.class);
        example.createCriteria().andEqualTo("skuId",sku);
        //图片列表
        List<ShopProductVariantImage> shopProductVariantImages = imageMapper.selectByExample(example);
        shopProductVariant.setSkuImageList(shopProductVariantImages);
        return shopProductVariant;
    }

    /**
     * 根据sku获取销售属性值列表，包括当前sku默认选中项
     * @param spu
     * @param sku
     * @return
     */
    @Override
    public List<ShopProductSaleAttr> spuSaleAttrListCheckBySku(Integer spu, Integer sku) {
        List<ShopProductSaleAttr> pmsProductSaleAttrs = productSaleAttrMapper.selectSpuSaleAttrListCheckBySku(spu,sku);
        return pmsProductSaleAttrs;
    }

    /**
     * 获取spu下sku销售关联信息，用于生成hash表
     * @param spu
     * @return
     */
    @Override
    public List<ShopProductVariant> getSkuSaleAttrValueListBySpu(Integer spu) {
        return skuMapper.selectSkuSaleAttrValueListBySpu(spu);
    }

    /**
     * 根据spu获取spu详细信息
     * @param spu
     * @return
     */
    @Override
    public ShopProductBase getSpuInfoBySpu(Integer spu) {
        return spumapper.selectByPrimaryKey(spu);
    }

    /**
     * 根据sku获取sku销售关联信息，用于加购信息中的商品销售属性显示
     * @param sku
     * @return
     */
    @Override
    public List<ShopProductVariantAttrValue> getSkuSaleAttrValueBySku(Integer sku) {
        return variantAttrValueMapper.selectSkuSaleAttrValueBySku(sku);
    }

    @Override
    public void saveSkuInfo(ShopProductVariant skuInfo) {
        //sku表
        skuMapper.insertSelective(skuInfo);
        Integer sku = skuInfo.getSku();
        //商品图片表
        List<ShopProductVariantImage> skuImageList = skuInfo.getSkuImageList();
        skuImageList.forEach(i->{
            i.setSkuId(sku);
            imageMapper.insertSelective(i);
        });

        //销售属性值关联表
        List<ShopProductVariantAttrValue> skuSaleAttrValueList = skuInfo.getSkuSaleAttrValueList();
        skuSaleAttrValueList.forEach(i->{
            i.setSkuId(sku);
            variantAttrValueMapper.insertSelective(i);
        });

    }

    @Override
    public List<ShopProductVariant> getSkuBySkuId(Integer spuId) {
        ShopProductVariant sku=new ShopProductVariant();
        sku.setSpu(spuId);
        return skuMapper.select(sku);
    }

    /**
     * 商品详情
     * @param sku
     * @return
     */
    @Override
    public Map<String,Object> getProductDetail(HttpServletRequest request,Integer sku) {
        ShopProductVariant  skuInfo= this.getSkuProductBySku(sku);
        Map<String,Object> map=new HashMap<>();
        //sku对象
        map.put("skuInfo",skuInfo);
        //销售属性列表
        List<ShopProductSaleAttr> pmsProductSaleAttrs = this.spuSaleAttrListCheckBySku(skuInfo.getSpu(),skuInfo.getSku());
        map.put("spuSaleAttrListCheckBySku",pmsProductSaleAttrs);
        List<ShopProductVariant> skuList=this.getSkuSaleAttrValueListBySpu(skuInfo.getSpu());
        //销售属性hash表，k->销售值id，v->sku,
        Map<String, String> skuSaleAttrHash = new HashMap<>();
        skuList.forEach(i->{
            String v= String.valueOf(i.getSku());
            List<ShopProductVariantAttrValue> skuSaleAttrValueList = i.getSkuSaleAttrValueList();
            StringBuilder k= new StringBuilder();
            for ( ShopProductVariantAttrValue skuSaleAttrValue: skuSaleAttrValueList){
                k.append(skuSaleAttrValue.getValueId()).append("|");
            }
            skuSaleAttrHash.put(k.toString(),v);
        });
        String skuSaleAttrHashJson = MapperUtils.mapToJson(skuSaleAttrHash);
        //库存
        ShopStock shopStock=shopStockService.getStockInfoBuSku(skuInfo.getSku());
        map.put("skuSaleAttrHash",skuSaleAttrHashJson);
        map.put("stockInfo",shopStock);
        //更新elk热度
        ExecutorService executorService = Executors.newCachedThreadPool();
        CountDownLatch doneSignal = new CountDownLatch(1);
        ServletContext context =  request.getServletContext();
        executorService.execute(new UpdateHotScoreRunable(context,doneSignal,String.valueOf(skuInfo.getSpu())));
        return map;
    }

}
